import {Util} from "./utils/util";
import {DataProcess} from "./code/dataProcess";
import {ParticleSystem} from "./code/particleSystem"
import { Layer } from "./core/Layer";
const Cesium = window.Cesium;

const defaultOptions = {
    maxParticles: 64 * 64,
    particleHeight: 100.0,
    fadeOpacity: 0.996,
    dropRate: 0.003,
    dropRateBump: 0.01,
    speedFactor: 1.0,
    lineWidth: 4.0,
    particlesTextureSize:64
}
//
export default class CesiumWind extends Layer{
    constructor(url,option=defaultOptions) {
        super(option.name);
        this.url = url;
        this.option = option;
    }
    updateOption(option){
        Object.assign(this.option, this.option, option);
        this.particleSystem.applyUserInput(this.option);
    }

    //添加到指定的map中
    _addToMap(map) {
        this._init(map.viewer);
    }
    //从map中移除
    _removeByMap(destroy) {
        this.scene.primitives.remove(this.cesiumLayer);
    }

    _init(viewer){
        this.scene = viewer.scene;
        this.camera = viewer.camera;
        this.viewerParameters = {
            lonRange: new Cesium.Cartesian2(),
            latRange: new Cesium.Cartesian2(),
            pixelSize: 0.0
        };
        // use a smaller earth radius to make sure distance to camera > 0
        // 使用更小的地球半径，以确保camera>0的距离
        this.globeBoundingSphere = new Cesium.BoundingSphere(Cesium.Cartesian3.ZERO, 0.99 * 6378137.0);
        this._updateViewerParameters();
        DataProcess.loadNetCDF(this.url).then((data) => {
                this.particleSystem = new ParticleSystem(this.scene.context, data, this.option, this.viewerParameters);
                this._addPrimitives();
                this._setupEventListeners();
            });
    }

    _addPrimitives() {
        var collection = new Cesium.PrimitiveCollection();
        // the order of primitives.add() should respect the dependency of primitives
        collection.add(this.particleSystem.particlesComputing.primitives.calculateSpeed);
        collection.add(this.particleSystem.particlesComputing.primitives.updatePosition);
        collection.add(this.particleSystem.particlesComputing.primitives.postProcessingPosition);

        collection.add(this.particleSystem.particlesRendering.primitives.segments);
        collection.add(this.particleSystem.particlesRendering.primitives.trails);
        collection.add(this.particleSystem.particlesRendering.primitives.screen);
        this.scene.primitives.add(collection);
        this.cesiumLayer = collection;
    }
   
    _updateViewerParameters() {
        var viewRectangle = this.camera.computeViewRectangle(this.scene.globe.ellipsoid);
        var lonLatRange = Util.viewRectangleToLonLatRange(viewRectangle);
        this.viewerParameters.lonRange.x = lonLatRange.lon.min;
        this.viewerParameters.lonRange.y = lonLatRange.lon.max;
        this.viewerParameters.latRange.x = lonLatRange.lat.min;
        this.viewerParameters.latRange.y = lonLatRange.lat.max;

        var pixelSize = this.camera.getPixelSize(
            this.globeBoundingSphere,
            this.scene.drawingBufferWidth,
            this.scene.drawingBufferHeight
        );

        if (pixelSize > 0) {
            this.viewerParameters.pixelSize = pixelSize;
        }
    }
    _setupEventListeners() {
        const that = this;

        this.camera.moveStart.addEventListener(function () {
            that.scene.primitives.show = false;
        });

        this.camera.moveEnd.addEventListener(function () {
            that._updateViewerParameters();
            that.particleSystem.applyViewerParameters(that.viewerParameters);
            that.scene.primitives.show = true;
        });

        var resized = false;
        window.addEventListener("resize", function () {
            resized = true;
            that.scene.primitives.show = false;
            that.scene.primitives.removeAll();
        });

        this.scene.preRender.addEventListener(function () {
            if (resized) {
                that.particleSystem.canvasResize(that.scene.context);
                resized = false;
                that._addPrimitives();
                that.scene.primitives.show = true;
            }
        });
    }
}
